﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Transactions;
using System.Xml.Linq;
using CYTS.Aoyou.Framework.Database.LinqToSql;

namespace CYTS.Aoyou.Framework.Database
{
    /// <summary>
    /// LinqToSql帮助类
    /// </summary>
    public class LinqToSqlHelper
    {
        /// <summary>
        /// 分页时每页最大查询数量
        /// </summary>
        const int MAX_QUERY_PAGESIZE = 2000;

        /// <summary>
        /// 获取数据实体数量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static int GetDataEntityCount<T>(string conn, Expression<Func<T, bool>> condition) where T : class, IDataEntity
        {
            XmlMappingSource mappingSource = XmlMappingSourceFactory.GetXmlMappingSource<T>();
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                using (DataContext context = new DataContext(conn, mappingSource))
                {
                    Table<T> table = context.GetTable<T>();
                    IQueryable<T> ret = table;
                    ret = ret.Where(condition);
                    return ret.Count();
                }
            }
        }

        /// <summary>
        /// 获取数据实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static List<T> GetDataEntityList<T>(string conn, Expression<Func<T, bool>> condition) where T : class, IDataEntity
        {
            return GetDataEntityList<T>(conn, condition, null, 0, MAX_QUERY_PAGESIZE);
        }

        /// <summary>
        /// 获取数据实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="condition"></param>
        /// <param name="orderBy"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static List<T> GetDataEntityList<T>(string conn, Expression<Func<T, bool>> condition, List<string> orderBy, int pageIndex, int pageSize) where T : class, IDataEntity
        {
            XmlMappingSource mappingSource = XmlMappingSourceFactory.GetXmlMappingSource<T>();
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
            {
                using (DataContext context = new DataContext(conn, mappingSource))
                {
                    Table<T> table = context.GetTable<T>();
                    IQueryable<T> ret = table;

                    if (orderBy != null && orderBy.Count > 0)
                    {
                        string orderString = orderBy[0];
                        IOrderedQueryable<T> orderRet;

                        if (orderBy[0].ToLower().IndexOf(" desc") > 0)
                        {
                            orderString = orderBy[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0];
                            orderRet = ret.OrderByDescending(orderString);
                        }
                        else
                        {
                            orderRet = ret.OrderBy(orderString);
                        }
                        for (int i = 1; i < orderBy.Count; i++)
                        {
                            orderString = orderBy[i];
                            if (orderBy[i].ToLower().IndexOf(" desc") > 0)
                            {
                                orderString =
                                    orderBy[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0];
                                orderRet = orderRet.ThenByDescending(orderString);
                            }
                            else
                            {
                                orderRet = orderRet.ThenBy(orderString);
                            }
                        }
                        ret = orderRet;
                    }

                    if (condition != null)
                    {
                        ret = ret.Where(condition);
                    }

                    if (pageIndex <= 0)
                    {
                        ret = ret.Take(pageSize);
                    }
                    else
                    {
                        ret = ret.Skip(pageIndex * pageSize).Take(pageSize);
                    }

                    List<T> res = ret.ToList();
                    return res;
                }
            }
        }


        /// <summary>
        /// 插入数据实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="entities"></param>
        public static void InsertDataEntityList<T>(string conn, List<T> entities) where T : class, IDataEntity
        {
            XmlMappingSource mappingSource = XmlMappingSourceFactory.GetXmlMappingSource<T>();
            using (DataContext context = new DataContext(conn, mappingSource))
            {
                Table<T> table = context.GetTable<T>();
                table.InsertAllOnSubmit(entities);
                context.SubmitChanges();
            }
        }

        /// <summary>
        /// 删除数据实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static int DeleteDataEntityList<T>(string conn, Expression<Func<T, bool>> condition) where T : class, IDataEntity
        {
            int result = 0;
            XmlMappingSource mappingSource = XmlMappingSourceFactory.GetXmlMappingSource<T>();
            using (DataContext context = new DataContext(conn, mappingSource))
            {
                Table<T> table = context.GetTable<T>();
                result = table.DeleteBatch<T>(condition);
            }
            return result;
        }

        /// <summary>
        /// 更新数据实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="condition"></param>
        /// <param name="evaluator"></param>
        /// <returns></returns>
        public static int UpdateDataEntityList<T>(string conn, Expression<Func<T, bool>> condition, Expression<Func<T, T>> evaluator) where T : class, IDataEntity
        {
            int result = 0;
            XmlMappingSource mappingSource = XmlMappingSourceFactory.GetXmlMappingSource<T>();
            using (DataContext context = new DataContext(conn, mappingSource))
            {
                Table<T> table = context.GetTable<T>();
                result = table.UpdateBatch<T>(condition, evaluator);
                return result;
            }
        }
    }
}
